
#include "SipSrvTransaction.hpp"
#include "SipUserAgent.hpp"

namespace wtsip{

CSipSrvTransaction::CSipSrvTransaction(SipMessage& request, CSipUserAgent& ua):
m_request(request),
m_ua(ua),
m_tid(request.getTransactionId()),
m_listener(0),
m_mth(request.method()),
m_State(SrvInitial)
{}

CSipSrvTransaction::~CSipSrvTransaction(){
    if (m_listener){
        m_listener->onDestroy(*this);
    }
}


bool CSipSrvTransaction::processIncoming(SipMessage* msg)
{
    if (!msg || !msg->isRequest())
        return false;

    if (m_listener){
        m_listener->onRequest(*this, *msg);
    }
    return true;
}


bool CSipSrvTransaction::processTimeOut(ApplicationMessage* msg){
    return false;
}


SipMessage* CSipSrvTransaction::createResponse(int code){
    SipMessage* msg = m_ua.createResponse(m_request, code);
    return msg;
}


bool CSipSrvTransaction::send(std::auto_ptr<SipMessage> msg){
    if (!msg.get() || !msg->isResponse())
        return false;

    int hCode = msg->header(h_StatusLine).responseCode() / 100;
    if (1 == hCode){
        if (SrvCompleted == m_State || SrvFailed == m_State){
            return false;
        }
        if (SrvInitial == m_State){
            setState(SrvProvisional);
        }
    } else if (2 == hCode){
        if (SrvFailed == m_State){
            return false;
        }
        if (SrvInitial == m_State || SrvProvisional == m_State){
            setState(SrvCompleted);
        }
    } else if (4 == hCode){
        if (SrvCompleted == m_State){
            return false;
        }
        if (SrvInitial == m_State || SrvProvisional == m_State){
            setState(SrvFailed);
        }
    }
    return m_ua.send(msg);
}


bool CSipSrvTransaction::registerListener(CSipSrvTransactionListener* callback){
    m_listener = callback;
    return true;
}

bool CSipSrvTransaction::unregisterListener(){
    m_listener = NULL;
    return true;
}


bool CSipSrvTransaction::bindDialog(CSipDialogBase* dialog){
    m_bindDialog = dialog;
    return true;
}


SipMessage& CSipSrvTransaction::getRequest(){
    return m_request;
}


resip::Data& CSipSrvTransaction::getTid(){
    return m_tid;
}


CSipDialogBase* CSipSrvTransaction::getBindDlg(){
    return m_bindDialog;
}


bool CSipSrvTransaction::setState(int state){
    m_State = state;
    return true;
}



}//namespace


